﻿using G.SL.Controls;
using G.SL.Navigate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace G.APITest
{
    public partial class Home : GBasePage
    {
        public Home()
        {
            InitializeComponent();
            App.Current.Exit += Current_Exit;
            RegisteKeyEvent();
            #region 菜单
            //文件
            MenuItem item1 = new MenuItem() { Name = "文件" };
            item1.Items.Add(new MenuItem() { Name = "新建项目", Command = new SL.MVVM.CallBackCommand(CreateProject) });
            item1.Items.Add(new MenuItem() { Name = "打开项目", Command = new SL.MVVM.CallBackCommand(OpenProject) });
            item1.Items.Add(new MenuItem() { Name = "在线项目", Command = new SL.MVVM.CallBackCommand(OpenOnlineProjects) });
            PageMenuService.GetMenu(this).Add(item1);
            //保存
            MenuItem item2 = new MenuItem() { Name = "保存" };
            item2.Items.Add(new MenuItem() { Name = "独立存储", Command = new SL.MVVM.CallBackCommand(SaveToIsolate) });
            item2.Items.Add(new MenuItem() { Name = "另存为", Command = new SL.MVVM.CallBackCommand(SaveAs) });

            PageMenuService.GetMenu(this).Add(item2);


            MenuItem item3 = new MenuItem() { Name = "用户" };
            item3.Items.Add(new MenuItem() { Name = "登录", Command = new SL.MVVM.CallBackCommand(Login) });
            item3.Items.Add(new MenuItem() { Name = "退出", Command = new SL.MVVM.CallBackCommand(Logout) });
            PageMenuService.GetMenu(this).Add(item3);

            cboSignType.ItemsSource = Enum.GetValues(typeof(Config.SignType));
            cboSignMethod.ItemsSource = Enum.GetValues(typeof(Config.SignMethod));
        }

        private void Logout(object p)
        {
            GloabalData.Instance.UserInfo = null;
            MessageBox.Show("成功退出！");
        }
        private void OpenOnlineProjects(object p)
        {
            if (GloabalData.Instance.UserInfo == null)
            {
                MessageBox.Show("请先登录");
                return;
            }
            ChildWindows.GetOnlineProjectChildWindow cw = new ChildWindows.GetOnlineProjectChildWindow();
            cw.Show();
            cw.Closed += (s, e) =>
            {
                Config = G.SL.Utils.SerializerHelp.JsonDeserialize<G.APITest.Config.APIProjectConfig>(cw.APIProjectConfigInfo.ProjectConfig);
            };
        }
        private void Login(object p)
        {
            ChildWindows.LoginChildWindow loginCW = new ChildWindows.LoginChildWindow();
            loginCW.Show();
            loginCW.Closed += (s, e) =>
            {

            };
        }

        private void CreateProject(object p)
        {
            if (MessageBox.Show("请先导出当前配置，以免丢失,是否保存?", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                SaveAs(null);
                CreateProject();
            }
            else
            {
                CreateProject();
            }
        }

        private void CreateProject()
        {
            ChildWindows.CreateProjectChildWindow w = new ChildWindows.CreateProjectChildWindow();
            w.Closed += (s, e) =>
            {
                if (w.DialogResult == true)
                {
                    var c = APITest.Config.APIProjectConfigService.CreateNewProject(w.txtProjectName.Text);
                    if (w.SelectedProjectTemplate != null)
                        c.APIRequestPartPath = w.SelectedProjectTemplate.LocalPath;
                    Config = c;
                }
            };
            w.Show();
        }


        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
        }

        private void OpenProject(object p)
        {
            var c = APITest.Config.APIProjectConfigService.ReadConfigFromFile();
            if (c != null)
                Config = c;
        }

        private void SaveAs(object p)
        {
            if (Config != null)
            {
                APITest.Config.APIProjectConfigService.SaveAs(Config);
            }
        }

        private void SaveToIsolate(object p)
        {
            if (Config != null)
            {
                APITest.Config.APIProjectConfigService.SaveToIsolate(Config);
                AppendMsg("成功保存到独立存储！");
                if (GloabalData.Instance.UserInfo != null)
                {
                    GloabalData.Instance.SampleClient.Execute(new Service.API.Request.APITest.UpdateApiTestConfigRequest() { UserId = GloabalData.Instance.UserInfo.ID, ProjectName = Config.ProjectName, ProjectConfig = APITest.Config.APIProjectConfigService.GetConfigString() }, (c) =>
                    {
                        if (c.IsOK)
                        {
                            AppendMsg("成功保存到线上！");
                        }
                        else
                        {
                            MessageBox.Show(c.Msg, "错误", MessageBoxButton.OK);
                        }
                    });
                }

            }
        }
            #endregion

        void Current_Exit(object sender, EventArgs e)
        {
            SaveToIsolate(null);
        }

        private void RegisteKeyEvent()
        {
            this.KeyUp += Home_KeyUp;
        }

        void Home_KeyUp(object sender, KeyEventArgs e)
        {
            ModifierKeys keys = Keyboard.Modifiers;
            if (keys == ModifierKeys.None)
            {
                if (e.Key == Key.F5)
                {
                    TestSelectedAPI();
                    e.Handled = true;
                }
            }
            else if (keys == ModifierKeys.Control)
            {
                if (e.Key == Key.S)
                {
                    SaveToIsolate(null);
                    e.Handled = true;
                }
            }
        }

        G.APITest.Config.APIProjectConfig config;
        G.APITest.Config.APIProjectConfig Config
        {
            get
            {
                return config;
            }
            set
            {
                config = value;
                this.DataContext = config;
                if (config != null)
                {
                    config.PropertyChanged -= config_PropertyChanged;
                    config.PropertyChanged += config_PropertyChanged;
                    Utils.MEFUtils.LoadPart(config.APIRequestPartPath, config);
                    config_PropertyChanged(null, new System.ComponentModel.PropertyChangedEventArgs("APIRequestPart"));
                    cboSignType.SelectionChanged -= cboSignType_SelectionChanged;
                    cboSignType.SelectionChanged += cboSignType_SelectionChanged;
                }
            }
        }
        private void cboSignType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (Config.SignType == APITest.Config.SignType.Customer)
            {
                if (Config.APIRequestPartPath == null)
                {
                    ChildWindows.CreateProjectChildWindow w = new ChildWindows.CreateProjectChildWindow(Config);
                    w.Closed += (s, _e) =>
                    {
                        if (w.DialogResult == true && w.SelectedProjectTemplate != null)
                        {
                            Config.APIRequestPartPath = w.SelectedProjectTemplate.LocalPath;
                            Utils.MEFUtils.LoadPart(Config.APIRequestPartPath, Config);
                        }
                        else
                            Config.SignType = APITest.Config.SignType.None;
                    };
                    w.Show();
                }
            }
            else if (Config.SignType == APITest.Config.SignType.None)
            {
                Config.APIRequestPartPath = null;
                Config.APIRequestPart = new G.APITest.Part.NormalRequest();
            };
        }

        void config_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "APIRequestPart")
            {
                if (config.APIRequestPart == null)
                {
                    config.APIRequestPart = new Part.NormalRequest();
                }
                else
                {
                    config.APIRequestPart.RaiseStatusCallBack = RaiseStatus;
                }
            }
        }
        private void RaiseStatus(string str)
        {
            AppendMsg(str);
        }
        bool isNavigate;
        // 当用户导航到此页面时执行。
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            if (!isNavigate)
            {
                Config = APITest.Config.APIProjectConfigService.ReadConfigFromIsolate();
                isNavigate = true;

            }
        }


        #region API编辑
        private void addAPIGroup_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            if (Config == null)
            {
                MessageBox.Show("无可用项目！");
                return;
            }
            var group = new Config.APIGroup();
            Config.APIGroups.Add(group);
            var tItem = treeview.ItemContainerGenerator.ContainerFromItem(group) as TreeViewItem;
            TreeItemUpdateLayout(tItem);
        }

        private static void TreeItemUpdateLayout(TreeViewItem tItem)
        {
            EventHandler eh = null;
            eh = (s, _e) =>
            {
                var editeControl = tItem.GetVisualDescendants<Controls.EditeControl>().FirstOrDefault();
                if (editeControl != null)
                {
                    editeControl.IsEdite = true;
                    tItem.LayoutUpdated -= eh;
                }
            };
            tItem.LayoutUpdated += eh;
        }
        private void addAPI_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            G.APITest.Config.APIGroup group = treeview.SelectedItem as G.APITest.Config.APIGroup;
            if (group == null)
            {
                MessageBox.Show("请选择一个组节点");
                return;
            }
            var api = new Config.APIConfig();
            group.APIConfigs.Add(api);
            var tItem = treeview.ItemContainerGenerator.ContainerFromItem(group) as TreeViewItem;
            TreeItemUpdateLayout(tItem.ItemContainerGenerator.ContainerFromItem(api) as TreeViewItem);
        }

        private void deleteNode_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            if (this.treeview.SelectedItem != null)
            {
                G.APITest.Config.APIGroup selectGroup = null;
                G.APITest.Config.APIConfig selectAPI = null;
                foreach (var group in this.Config.APIGroups)
                {
                    if (group == treeview.SelectedItem)
                    {
                        selectGroup = group;
                    }
                    else
                    {
                        foreach (var api in group.APIConfigs)
                        {
                            if (api == treeview.SelectedItem)
                            {
                                selectGroup = group;
                                selectAPI = api;
                                break;
                            }
                        }
                    }
                    if (selectGroup != null)
                        break;
                }

                if (selectAPI != null)
                {
                    if (MessageBox.Show("确定要删除该API吗", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        selectGroup.APIConfigs.Remove(selectAPI);
                    }
                }
                else
                {
                    if (MessageBox.Show("确定要删除该组吗", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        Config.APIGroups.Remove(selectGroup);
                    }
                }

            }
            else
            {
                MessageBox.Show("请选择一个节点进行删除");
            }
        }

        private void apiEditeTXT_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                TextBox t = sender as TextBox;
                if (string.IsNullOrWhiteSpace(t.Text))
                {
                    MessageBox.Show("请输入名称");
                    return;
                }
                Controls.EditeControl editeControl = treeview.GetVisualDescendants<Controls.EditeControl>().Where(c => c.DataContext == t.DataContext).FirstOrDefault(c => c.IsEdite = true);
                if (t.DataContext is APITest.Config.APIGroup)
                {
                    var group = t.DataContext as APITest.Config.APIGroup;
                    group.GroupName = t.Text;
                }
                else if (t.DataContext is APITest.Config.APIConfig)
                {
                    var config = t.DataContext as Config.APIConfig;
                    config.Name = t.Text;
                }
                editeControl.IsEdite = false;
            }
        }

        private void deleteAPIHeader_Click(object sender, RoutedEventArgs e)
        {
            APITest.Config.APIConfig api = treeview.SelectedItem as APITest.Config.APIConfig;
            FrameworkElement f = sender as FrameworkElement;
            APITest.Config.KVPair kvp = f.DataContext as APITest.Config.KVPair;
            api.Headers.Remove(kvp);
        }

        private void btnDeleteAPIParamter_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("确定要删除改参数吗？", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                Button btn = sender as Button;
                G.APITest.Config.Paramter p = btn.DataContext as G.APITest.Config.Paramter;
                APITest.Config.APIConfig apiconfig = treeview.SelectedItem as APITest.Config.APIConfig;
                apiconfig.Paramters.Remove(p);
            }
        }

        private void addAPIParam_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            APITest.Config.APIConfig apiconfig = treeview.SelectedItem as APITest.Config.APIConfig;
            if (apiconfig != null)
            {
                apiconfig.Paramters.Add(new Config.Paramter());
            }
        }

        private void addGlobalParam_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            Config.GlobalParams.Add(new Config.KVPair());
        }
        private void deleteGlobalParam_Click(object sender, RoutedEventArgs e)
        {
            FrameworkElement f = sender as FrameworkElement;
            G.APITest.Config.KVPair kvp = f.DataContext as G.APITest.Config.KVPair;
            Config.GlobalParams.Remove(kvp);
        }

        private void deleteGlobalHeader_Click(object sender, RoutedEventArgs e)
        {
            FrameworkElement f = sender as FrameworkElement;
            G.APITest.Config.KVPair kvp = f.DataContext as G.APITest.Config.KVPair;
            Config.GlobalHeaders.Remove(kvp);
        }

        private void addAPIHeader_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            APITest.Config.APIConfig api = treeview.SelectedItem as APITest.Config.APIConfig;
            if (api != null)
            {
                api.Headers.Add(new Config.KVPair());
            }
        }

        private void addGlobalHeader_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            Config.GlobalHeaders.Add(new Config.KVPair());
        }
        #endregion
        //[System.ComponentModel.Composition.Import(typeof(G.SL.Part.IPlugin))]
        //public G.SL.Part.IPlugin mypart { get; set; }

        #region API测试
        private void TestSelectedAPI()
        {
            //WebClient client = new WebClient();
            //client.OpenReadCompleted += client_OpenReadCompleted;
            //client.OpenReadAsync(new Uri("http://localhost:37436/ClientBin/G.APITest.Part.dll"));
            //return;
            if (Config.APIRequestPart == null)
            {
                MessageBox.Show("无可用请求插件或插件已失效");
                return;
            }
            APITest.Config.APIConfig api = treeview.SelectedItem as APITest.Config.APIConfig;
            if (api == null)
            {
                MessageBox.Show("请选择一个API进行测试");
                return;
            }

            //if (Config.IsOauthSign)
            //{
            //    G.SL.Net.Oauth.Oauth2Config.Request_Authorize_Url = Config.Request_Authorize_Url;
            //    G.SL.Net.Oauth.Oauth2Config.ClientID = Config.APPKey;
            //    G.SL.Net.Oauth.Oauth2Config.ClientSecret = Config.APPSecret;
            //    G.SL.Net.Oauth.Oauth2Config.RedirectUri = Config.RedirectUri;
            //    G.SL.Net.Oauth.Oauth2Config.Token_Authorize_Url = Config.Token_Authorize_Url;
            //    if (G.SL.Net.Oauth.OAuth2AccessToken.CurrentToken == null)
            //    {
            //        G.SL.Net.Oauth.Oauth2Valid.Valid(Config.ProjectName, c =>
            //        {
            //            RequestOauth(api);
            //        });
            //    }
            //    else
            //    {
            //        RequestOauth(api);
            //    }
            //    return;
            //}
            AppendMsg("开始测试API：" + api.Name);
            progressBar.IsIndeterminate = true;
            Config.APIRequestPart.CreateRequestAsync(Config, api, (request) =>
            {
                if (request == null)
                {
                    AppendMsg("无法测试API：无法创建请求，请检查模版是否正确");
                    progressBar.IsIndeterminate = false;
                    return;
                }
                request.Request((ex, str) =>
                {
                    DoResult(ex, str, api);
                    this.Dispatcher.BeginInvoke(() =>
                    {
                        progressBar.IsIndeterminate = false;
                    });
                });
            });
        }
        private void DoResult(WebException ex, string str, APITest.Config.APIConfig api)
        {
            if (ex == null)
            {
                AppendMsg("请求成功！");
                this.Dispatcher.BeginInvoke(() =>
                {
                    api.TestResult = str;
                });
            }
            else
            {
                AppendMsg("请求失败：" + ex.Message, Colors.Red);
            }
        }
        //private void RequestOauth(G.APITest.Config.APIConfig api)
        //{
        //    try
        //    {
        //        AppendMsg(string.Format("正在测试API：{0}", api.Name));
        //        string uri = Config.APIBaseUri + "/" + api.Path;
        //        G.SL.Net.Oauth.Oauth2HttpGet get = new G.SL.Net.Oauth.Oauth2HttpGet(uri);
        //        foreach (var item in api.Paramters)
        //        {
        //            get.Params.Add(item.Name, item.Value);
        //        }
        //        get.Request((ex, str) =>
        //        {
        //            if (ex != null)
        //            {
        //                this.Dispatcher.BeginInvoke(() =>
        //                {
        //                    G.SL.Net.Oauth.Oauth2Valid.RefreshToken(Config.ProjectName, c =>
        //                    {
        //                        RequestOauth(api);
        //                    });
        //                });
        //            }
        //            else
        //                DoResult(ex, str, api);
        //        });
        //    }
        //    catch (Exception e)
        //    {
        //        AppendMsg(e.ToString());
        //    }
        //}

        private void AppendMsg(string msg, Color? color = null)
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                Paragraph p = new Paragraph();
                if (color == null)
                    p.Inlines.Add(msg);
                else
                {
                    p.Inlines.Add(new Run { Text = msg, Foreground = new SolidColorBrush(color.Value) });
                }
                p.Inlines.Add(new LineBreak());
                txtStatus.Blocks.Add(p);
                ScrollViewer scroll = txtStatus.Parent as ScrollViewer;
                scroll.ScrollToVerticalOffset(scroll.ScrollableHeight);
            });
        }

        private void clearStatus_Click(object sender, RoutedEventArgs e)
        {
            this.txtStatus.Blocks.Clear();
        }

        private void btnValidOauth2_Click(object sender, RoutedEventArgs e)
        {

        }
        #endregion

        private void updatePlugin_Click(object sender, RoutedEventArgs e)
        {
            Utils.MEFUtils.UpdatePart(Config);
        }

        //private void addPlugin_Click(object sender, RoutedEventArgs e)
        //{
        //    ChildWindows.CreateProjectChildWindow w = new ChildWindows.CreateProjectChildWindow(Config);
        //    w.Closed += (s, _e) =>
        //    {
        //        if (w.DialogResult == true)
        //        {
        //            Config.APIRequestPartPath = w.SelectedProjectTemplate.LocalPath;
        //            Utils.MEFUtils.LoadPart(Config.APIRequestPartPath, Config);
        //        }
        //    };
        //    w.Show();
        //}

        private void createClass_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            APITest.Config.APIConfig api = treeview.SelectedItem as APITest.Config.APIConfig;
            if (api == null || string.IsNullOrWhiteSpace(api.TestResult))
                this.NavigationService.Navigate(new Uri("/CreateClassPage", UriKind.Relative));
            else
            {
                this.Navigate("/CreateClassPage", api.TestResult);
                //this.NavigationService.Navigate(new Uri(string.Format("/CreateClassPage?data={0}", Uri.EscapeDataString(api.TestResult)), UriKind.Relative));
            }
        }

        private void btnTestAPi_Click(object sender, RoutedEventArgs e)
        {
            TestSelectedAPI();
        }

        private void treeview_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
        }
    }
}